#include "app_buffer.h"
static SubBuffer_t *app_subfferInit(int nSize)
{
    SubBuffer_t *pSubBuffer = (SubBuffer_t *)malloc(sizeof(SubBuffer_t));
    if (pSubBuffer != NULL)
    {

        pSubBuffer->pBuffer = (char *)malloc(nSize);
        pSubBuffer->nSize = nSize;
        pSubBuffer->len = 0;
    }
    return pSubBuffer;
}
// 定义切换缓冲区函数
static void app_bufferSwitch(Buffer *pBuffer)
{
    //加锁
    pthread_mutex_lock(&pBuffer->write_mutex);
    pBuffer->readindex = !(pBuffer->readindex);
    pBuffer->writeindex = !(pBuffer->writeindex);
    pthread_mutex_unlock(&pBuffer->write_mutex);
}
Buffer *app_BufferInit(int nSize)
{
    Buffer *pBuffer = (Buffer *)malloc(sizeof(Buffer));
    if (pBuffer != NULL)
    {
        pBuffer->pSubBuffer[0] = app_subfferInit(nSize);
        pBuffer->pSubBuffer[1] = app_subfferInit(nSize);

        pBuffer->readindex = 0;
        pBuffer->writeindex = 1;
        pthread_mutex_init(&pBuffer->read_mutex, NULL);
        pthread_mutex_init(&pBuffer->write_mutex, NULL);

        return pBuffer;
    }
    return NULL;
}

void app_BufferDestroy(Buffer *Buffer)
{
    if (Buffer != NULL)
    {
        free(Buffer->pSubBuffer[0]->pBuffer);
        free(Buffer->pSubBuffer[1]->pBuffer);
        free(Buffer->pSubBuffer[0]);
        free(Buffer->pSubBuffer[1]);
        free(Buffer);
        pthread_mutex_destroy(&Buffer->read_mutex);
    }
}

int app_BufferWrite(Buffer *pBuffer, char *buffer, int bufferSize)
{

    if (bufferSize > MAX_BUFFER_SIZE)
    {
        log_error("buffer size is too large");
        return -1;
    }
    
    pthread_mutex_lock(&pBuffer->write_mutex);

    SubBuffer_t *pWriteSubBuffer = pBuffer->pSubBuffer[pBuffer->writeindex];

    if (pWriteSubBuffer->len + bufferSize + 1 > pWriteSubBuffer->nSize)
    {
        log_error("buffer is full");
        pthread_mutex_unlock(&pBuffer->write_mutex);
        return -1;
    }
    pWriteSubBuffer->pBuffer[pWriteSubBuffer->len] = bufferSize;

    memcpy(pWriteSubBuffer->pBuffer + pWriteSubBuffer->len + 1, buffer, bufferSize);

    pWriteSubBuffer->len += bufferSize + 1;

    pthread_mutex_unlock(&pBuffer->write_mutex);
    return 0;
}

int app_BufferRead(Buffer *pBuffer, char *buffer, int bufferSize)
{
    // 加锁
    pthread_mutex_lock(&pBuffer->read_mutex);
    int count = 0;
    SubBuffer_t *pReadSubBuffer;
secondread:
    pReadSubBuffer = pBuffer->pSubBuffer[pBuffer->readindex];
    int dataSize = pReadSubBuffer->pBuffer[0];
    if (pReadSubBuffer->len == 0)
    {
        // 切换读写缓冲区
        
        app_bufferSwitch(pBuffer);
        if (count)
        {
            pthread_mutex_unlock(&pBuffer->read_mutex);
            return -1;
        }
        
        count ++;
        goto secondread;
        // return -1;
    }
    if (bufferSize < pReadSubBuffer->pBuffer[0])
    {
        log_error("buffer size is too small");
        pthread_mutex_unlock(&pBuffer->read_mutex);
        return -1;
    }
    memcpy(buffer, pReadSubBuffer->pBuffer + 1, pReadSubBuffer->pBuffer[0]);

    pReadSubBuffer->len -= pReadSubBuffer->pBuffer[0] + 1;

    memmove(pReadSubBuffer->pBuffer, pReadSubBuffer->pBuffer + pReadSubBuffer->pBuffer[0] + 1, pReadSubBuffer->len);

    pthread_mutex_unlock(&pBuffer->read_mutex);
    
    return dataSize;

}